#include "rational.h"
#include <cstdlib>
#include <cstdio>

static int gcd(int a, int b) {
	if (a == 0) {
		return b;
	}
	return gcd(b%a, a);
}

void Rational::print() const {
	printf("%d/%d\n", p, q);
}

int Rational::getNumerator() const {
	return p;
}

int Rational::getDenominator() const {
	return q;
}

Rational::Rational(int m, int n): p(m), q(n) {
}

Rational::Rational(const Rational &r): p(r.p), q(r.q) {
}

Rational& Rational::operator= (const Rational& r) {
	p = r.p;
	q = r.q;
	return *this;
}

Rational& Rational::operator+= (const Rational& r) {
	int m = p * r.q + this->q * r.p;
	int n = q * r.q;
	p = m;
	q = n;
	normalize();
	return *this;
}

Rational& Rational::operator-= (const Rational& r) {
	int m = p * r.q - this->q * r.p;
	int n = q * r.q;
	p = m;
	q = n;
	normalize();
	return *this;
}

Rational& Rational::operator*= (const Rational& r) {
	int m = p * r.p;
	int n = q * r.q;
	p = m;
	q = n;
	normalize();
	return *this;
}

Rational& Rational::operator/= (const Rational& r) {
	int m = p * r.q;
	int n = q * r.p;
	p = m;
	q = n;
	normalize();
	return *this;
}

Rational& Rational::operator++() {
	(*this)++;
	return *this;
}

Rational Rational::operator++(int) {
	Rational tmp(*this);
	(*this) += Rational(1);
	return tmp;
}

Rational& Rational::operator--() {
	(*this)--;
	return *this;
}

Rational Rational::operator--(int) {
	Rational tmp(*this);
	(*this) -= Rational(1);
	return tmp;
}

void Rational::normalize() {
	int g = gcd(abs(p), abs(q));
	p /= g;
	q /= g;
}

Rational::operator double () {
	return p * 1.0 / q;
}

Rational operator+ (const Rational& a, const Rational& b) {
	Rational res(a);
	res += b;
	return res;
}

Rational operator- (const Rational& a, const Rational& b) {
	Rational res(a);
	res -= b;
	return res;
}

Rational operator* (const Rational& a, const Rational& b) {
	Rational res(a);
	res *= b;
	return res;
}

Rational operator/ (const Rational& a, const Rational& b) {
	Rational res(a);
	res /= b;
	return res;
}

bool operator== (const Rational& a, const Rational& b) {
	return (a.getNumerator() == b.getNumerator() &&
		a.getDenominator() == b.getDenominator());
}

bool operator!= (const Rational& a, const Rational& b) {
	return !(a == b);
}

bool operator<= (const Rational& a, const Rational& b) {
	return !(a > b);
}

bool operator>= (const Rational& a, const Rational& b) {
	return !(a < b);
}

bool operator<  (const Rational& a, const Rational& b) {
	return (a.getNumerator() * b.getDenominator() < 
		a.getDenominator() * b.getNumerator());
}

bool operator>  (const Rational& a, const Rational& b) {
	return !(a < b || a == b);
}
